#pragma once
#include "pulse/pulseaudio.h"
#include <QMap>
#include <QObject>
#include <QThread>

struct PulseDevice {
    int index;
    QString name;
    QString desc;
    quint32 volume;
};

Q_DECLARE_METATYPE(PulseDevice)

// PulseAudio 客户端类
class PulseClient : public QObject {
    Q_OBJECT
public:
    // 事件枚举
    enum Event {
        E_Sink_Add, // 添加输出设备
        E_Sink_Remove, // 移除输出设备
        E_Sink_Vol_Changed, // 输出设备音量改变
        E_Source_Add, // 添加输入设备
        E_Source_Remove, // 移除输入设备
        E_Source_Vol_Changed, // 输入设备音量改变

        E_Sink_Input_Add,
    };

    // 状态枚举
    enum State {
        Ready, // 就绪状态
    };

    PulseClient(QString lineinName);
    ~PulseClient();
    void appendWhiteList(QString k, QString v);

public slots:
    void setDefaultOutputDevice(QString name);
    void setDefaultInputDevice(QString name);

    void setOutputVolume(QString name, quint32 vol);
    void setInputVolume(QString name, quint32 vol);

    void monitorOutputVolumeLevel(bool onoff);
    void monitorInputVolumeLevel(bool onoff);

    // 使用默认输出设备playback音频文件
    void startPlayback(QString file);
    // 停止playback
    void stopPlayback();

    // 使用默认输入设备record到音频文件
    void startRecord(QString savefile);
    //停止record
    void stopRecord();

    void getAllDevices();
    void muteSystemSource(bool mute);
    void playbackLineIn(bool play);

private slots:
    bool isReady();

signals:
    void volumeMeter(bool output, float meter);
    // 状态改变信号
    void stateChanged(PulseClient::State e);
    // 订阅事件信号
    void subEvent(PulseClient::Event e, PulseDevice info);
    void getAllDevicesCB(bool sink, PulseDevice device);

private:
    // 启动 PulseClient
    void start();

    // 上下文状态改变回调函数
    void onContextStateChange(pa_context_state_t state);

    // 服务器信息回调
    void onServerInfo(const pa_server_info* info);
    void stopPcmMonitor(pa_stream* s);
    pa_stream* pcmMonitor(QString name);
    void notify(Event ev, uint32_t index);

    // 订阅事件回调函数
    static void subscribeCallback(pa_context* c, pa_subscription_event_type_t t, uint32_t index, void* userdata);

private:
    pa_mainloop* m_loop; // PulseAudio 主循环
    pa_mainloop_api* m_api; // PulseAudio 主循环 API
    pa_context* m_ctx = nullptr; // PulseAudio 上下文
    QThread m_thread; // PulseClient 运行所在的线程
    QString m_defaultSinkName, m_defaultSourceName, m_lineinSourceName;
    QList<PulseDevice> m_sinks, m_sources;
    pa_stream *m_sinkStream, *m_sourceStream, *m_lineinStream;
    bool m_muteSystemSource = false;
    QMap<QString, QString> m_muteWhiteList;
};

Q_DECLARE_METATYPE(PulseClient::Event)
